from wtforms import ValidationError
import os
from wtforms import Field, Form
import wtforms.validators as vd
from app.libs.enums import RType
# 自定义校验器


class IDValidator:
    """ 校验ID的合法性，>=1合法 """

    def __init__(self, nullable=False):
        self.nullable = nullable

    def __call__(self, form: Form, field: Field):
        if self.nullable and not field.data:
            return True
        vd.data_required().__call__(form, field)
        vd.number_range(min=1,).__call__(form, field)


class NullableEmailValidator:
    """ 允许为空的邮箱校验器 """

    def __call__(self, form: Form, field: Field):
        if field.data:
            vd.email().__call__(form, field)


class PathValidator:
    """ 文件路径是否在本地存在 """

    def __call__(self, form: Form, field: Field):
        vd.data_required().__call__(form, field)  # 必须传入
        if not os.path.exists(field.data):
            message = field.gettext(
                "path is not exists!"
            )
            raise ValidationError(message=message)
        else:
            return


class TypeValidator():
    """ 校验传入的资源类型是否合法,并且必须要传入 """

    def __call__(self, form: Form, field: Field):

        vd.data_required().__call__(form, field)
        try:
            # 校验并 同时 挂载type到form上
            form.resource_type = RType(field.data)
        except Exception as e:
            message = field.gettext(
                f"type值错误 (提示：{RType.get_kv_dict()})"
            )
            raise ValidationError(message=message)


class UrlUnquote():
    def __call__(self, form: Form, field: Field):
        if field.data:
            from urllib.parse import unquote
            field.data = unquote(field.data)


class NullableNumberRangeValidator():

    def __init__(self, min=None, max=None):
        self.min = min
        self.max = max

    def __call__(self, form: Form, field: Field):
        if field.data:
            vd.number_range(min=self.min, max=self.max).__call__(form, field)


class VSSpeedValidator():
    def __call__(self, form: Form, field: Field):
        if field.data is not None:
            try:
                field.data = float(field.data)
                NullableNumberRangeValidator(min=0.0001).__call__(form, field)
            except Exception as e:
                message = field.gettext(
                    f"{field.name}：请传入正数"
                )
                raise ValidationError(message=message)


class VSStepValidator():
    def __call__(self, form: Form, field: Field):
        if field.data is not None:
            try:
                field.data = float(field.data)
                NullableNumberRangeValidator(min=0.0001).__call__(form, field)
            except Exception as e:
                if field.data != 'fps':
                    message = field.gettext(
                        f"{field.name}：应该大于0，或为'fps'"
                    )
                    raise ValidationError(message=message)
                else:
                    field.data = 'fps'
